#!/usr/bin/env python3
import uuid
import base64
import os
import sys
from PyQt5.QtCore import *
from PyQt5.QtSql import (QSqlDatabase, QSqlQuery, QSqlTableModel)
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import time
import datetime,math
from q4 import InputDialog

import win32con
import ctypes
import ctypes.wintypes
import threading
RUN=False #用来传递运行一次的参数
mainfram = None
user32 = ctypes.windll.user32  #加载user32.dll
id1=105 #注册热键的唯一id，用来区分热键

main_frame  = None


MAC = True
try:
    from PyQt5.QtGui import qt_mac_set_native_menubar
except ImportError:
    MAC = False

ID, CATEGORY, SHORTDESC, LONGDESC,FONTSIZE = range(5)


from ctypes import c_bool, c_int, WINFUNCTYPE, windll
from ctypes.wintypes import UINT

prototype = WINFUNCTYPE(c_bool, c_int, c_int, UINT, UINT)
paramflags = (1, 'hWnd', 0), (1,'id', 0), (1,'fsModifiers', 0), (1,'vk', 0)







class FirstWindow(QWidget):

    close_signal = pyqtSignal()
    def __init__(self, parent=None):
        # super这个用法是调用父类的构造函数
        # parent=None表示默认没有父Widget，如果指定父亲Widget，则调用之
        super(FirstWindow, self).__init__(parent)
        self.resize(250,100)
        # self.leName = QLineEdit(self)
        # self.leName.setPlaceholderText(u'用户名')
        self.lePassword = QLineEdit(self)
        self.lePassword.setEchoMode(QLineEdit.Password)
        self.lePassword.setPlaceholderText(u'密码')
        self.run_day = time.localtime().tm_yday
        self.now_day = time.localtime().tm_yday
        self.m30_7once = True

        self.pbLogin = QPushButton(u'登录', self)
        self.pbLogin.setFocus()
        # self.pbCancel = QPushButton(u'机器码', self)
        self.setWindowIcon(QIcon("ico.ico"))
        self.setWindowTitle("WDMSET")
        # self.setWindowFlags( Qt.WindowMaximizeButtonHint|Qt.WindowMinimizeButtonHint| Qt.WindowStaysOnTopHint)
        self.myquery = QSqlQuery()
        self.removelist = []


        # self.pbLogin.clicked.connect(self.login)
        # self.pbCancel.clicked.connect(self.reject)

        layout = QVBoxLayout()
        # layout.addWidget(self.leName)
        layout.addWidget(self.lePassword)


        # 放一个间隔对象美化布局
        spacerItem = QSpacerItem(20, 48, QSizePolicy.Minimum, QSizePolicy.Expanding)
        layout.addItem(spacerItem)

        # 按钮布局
        buttonLayout = QHBoxLayout()
        # 左侧放一个间隔
        spancerItem2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        buttonLayout.addItem(spancerItem2)
        buttonLayout.addWidget(self.pbLogin)
        # buttonLayout.addWidget(self.pbCancel)

        layout.addLayout(buttonLayout)

        self.setLayout(layout)

        if not regised():
            value, ok = QInputDialog.getText(self, "提醒", "未注册，请输入注册码，完成注册", QLineEdit.Normal, "请输入注册码，您的机器码为:"+get_mac_address())
            self.register(value)

        try:
            thread = MyThread()  # 创建一个线程
            thread.sec_changed_signal.connect(self.update)  # 线程发过来的信号挂接到槽：update
            self.pbLogin.clicked.connect(lambda: thread.start())
            thread.start()

        except ZeroDivisionError as err:  # as 加原因参数名称
            print('Exception: ', err)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.hide()

    def close(self):
        self.hide()
        return False


                # try:
        #     threadHot = MyThreadHot()  # 创建一个线程
        #     threadHot.sec_changed_signal.connect(self.hot)  # 线程发过来的信号挂接到槽：update
        #     self.pbLogin.clicked.connect(lambda: threadHot.start())
        #     threadHot.start()
        #
        # except ZeroDivisionError as err:  # as 加原因参数名称
        #     print('Exception: ', err)



        self.m30_7once = True #每天提醒一次 True为未提醒 False 为已提醒



        # self.RegisterHotKey = prototype(('RegisterHotKey', windll.user32), paramflags)
        #
        # r = self.RegisterHotKey(c_int(self.mainWindow.winId()), HOT_KEY_ID, config.modifier, ord(config.hotkey.upper()))
        # if not r:
        #     QMessageBox.critical(None, 'Hot key', "Can't Register Hotkey Win + Z")
        #     sys.exit(1)



    def hot(self):
        print('11')

    #     # self.show()

    def register(self,value):
        if value == encode(get_mac_address()):
            print("注册码正确，写入文件返回成功")
            with open('./register', 'w') as f:
                f.write(value)
                f.close()
        else:
            value, ok = QInputDialog.getText(self, "提醒", "注册码不正确，请重新输入注册码，完成注册", QLineEdit.Normal,
                                             "请输入注册码，您的机器码为:" + get_mac_address())
            self.register(value)

    def update(self, sec):
        # QMessageBox.about(self, '提醒', "密码输入错误，请重试")
        self.now_day = time.localtime().tm_yday
        if self.run_day != self.now_day:
            self.m30_7once = True
        print(str(sec))
        self.process()

        # self.btn = QToolButton(self)
        # self.btn
        # .setText("click")

    def process(self):
        #threading.Thread(target=self.threadRun).start()
        select_date = self.myquery.exec('select * from reference')
        print(select_date)
        try:
            while self.myquery.next():
                print("提醒前查询"+str(self.myquery.value(0)) + self.myquery.value(1) + self.myquery.value(2))
                self.showWarn(self.myquery.value(1), self.myquery.value(2), self.myquery.value(3),str(self.myquery.value(0)),str(self.myquery.value(4)))
        except ZeroDivisionError as err:  # as 加原因参数名称
            print('Exception: ', err)
        finally:
            self.m30_7once = False
            for rminfo in self.removelist:
                self.removeWarn(rminfo["vid"], rminfo["value"])
            str1 = 'QWidget{font-size:12px;}'
            self.setStyleSheet(str1)


    def removeWarnbefore(self,vid, value):
        sdict = {}
        sdict['vid']=vid
        sdict['value']=value
        self.removelist.append(sdict)
        print(self.removelist)


    def showWarn(self,vtime,vdesc,vyzm,vid,vfontsize):
        try:
            category = vtime
            print(category)
            waring_t = time.strptime(category, "%Y-%m-%d")
            print(waring_t)
            waring_time = time.mktime(waring_t)
            print(waring_time)
            now = time.localtime(time.time())
            nowtime = time.time()
            print(now)
            print(nowtime)
            str1 = 'QWidget{font-size:' + str(vfontsize) + 'px;}'
            print(str1)

            left = math.floor((waring_time - nowtime)/(24*60*60))
            print("left"+str(left))
            if left<0:
                left = 0

            desc = vdesc
            desc = desc.replace('{left}', '<span style=color:red; size=50px >' + str(left) + '</span>')
            warning = "提醒时间：" + category + ";提醒内容:" + desc;
            print("验证码为："+vyzm)
            if left < 30:
                if left > 7 and self.m30_7once:
                    if vyzm == '是':
                        print('进入大于七天')
                        infoBox = QInputDialog()
                        self.setStyleSheet(str1)
                        # self.setWindowFlags(Qt.WindowMinimizeButtonHint| Qt.WindowStaysOnTopHint)
                        value, ok = infoBox.getText(self, "提醒", desc, QLineEdit.Normal, '输入激活码，清除本任务')
                        print(value)
                        self.removeWarnbefore(vid, value)
                    else:
                        infoBox = QMessageBox()
                        infoBox.setWindowTitle('提醒')
                        infoBox.setText(desc)
                        # infoBox.setWindowFlags(Qt.WindowMaximizeButtonHint | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint)
                        infoBox.setStyleSheet(str1)
                        infoBox.exec()
                if left <= 7:
                    if vyzm == '是':
                        print('进入小于七天')
                        infoBox = QInputDialog()
                        # infoBox.setWindowFlags(Qt.WindowCloseButtonHint)
                        self.setStyleSheet(str1)
                        # self.setWindowFlags(Qt.WindowCloseButtonHint)
                        value, ok = infoBox.getText(self, "提醒1", desc, QLineEdit.Normal, '输入激活码，清除本任务')
                        print(value)
                        self.removeWarnbefore(vid, value)
                        # value, ok = infoBox.exec()
                        # value, ok = QInputDialog.getText(self, "提醒", desc, QLineEdit.Normal, "输入激活码，清除本任务")
                    else:
                        infoBox = QMessageBox()
                        infoBox.setWindowTitle('提醒')
                        infoBox.setText(desc)
                        infoBox.setWindowFlags(Qt.WindowCloseButtonHint)
                        infoBox.setStyleSheet(str1)
                        infoBox.exec()
        except Exception as e:
            print(e)
            print('download exception %s' % str1)


    def removeWarn(self,vid,value):

        print(vid+" 验证码为:"+value)
        try:
            sql = "select count(*) from sjm where sjmm='"+value+"'"
            print(sql)
            self.myquery.exec_(sql)
            print(self.myquery)
            if self.myquery.next():
                num = self.myquery.value(0)
                print(self.myquery.value(0))
                if num == 1:
                    print('正确的随机码')
                    vsql = "delete  from reference where id='" + vid + "'"
                    print(vsql)
                    self.myquery.exec_(vsql)

                    vsql = "delete  from sjm where sjmm='" + value + "'"
                    print(vsql)
                    self.myquery.exec_(vsql)

                # return True
            else:
                print('错误的随机码')
                # return True
        except ZeroDivisionError as err:  # as 加原因参数名称
            print('Exception: ', err)
        finally:
            self.myquery.exec("commit;")
            print('afeiafei')
            # self.update()




    def login(self,fm):
        """返回True或False"""
        input_pw = self.lePassword.text()
        print(input_pw)
        if input_pw == '120607':
            print(fm)
            fm.show()
            self.hide()
        else:
            QMessageBox.about(self, '提醒', "密码输入错误，请重试")
    def reject(self):
        QInputDialog.getText(self, "信息", "本机机器码为：", QLineEdit.Normal, get_mac_address())

    def closeEvent(self, event):
        self.close_signal.emit()
        self.close()



def get_mac_address():
    mac=uuid.UUID(int = uuid.getnode()).hex[-12:]
    mac = ":".join([mac[e:e+2] for e in range(0,11,2)])
    macstr = mac.replace(':', '')
    return macstr

def encode(str):
    bytesString = str.encode(encoding="utf-8")
    #print(bytesString)
    # base64 编码
    encodestr = base64.b64encode(bytesString)
    #print(encodestr)
    print(encodestr.decode())
    return encodestr.decode()

def decode(encode_str):
    decodestr = base64.b64decode(encode_str)
    #print(decodestr.decode())
    return decodestr.decode()

import sqlite3
def getencode():
    try:
        conn = sqlite3.connect('reference.db')
        cursor = conn.cursor()
        sql = '''select sjmm from sjm limit 1'''
        results = cursor.execute(sql)
        one_sjm = results.fetchone()[0]
        sql = "delete from sjm where sjmm = '"+one_sjm+"'"
        print(sql)
        cursor.execute(sql)
        conn.commit()
        return one_sjm
    except ZeroDivisionError as err:  # as 加原因参数名称
            print('Exception: ', err)

# mac = get_mac_address()
# encode_str = encode(mac)
# print(decode(encode_str))

class MyThread(QThread):
    sec_changed_signal = pyqtSignal(int)  # 信号类型：int

    def __init__(self, sec=1000, parent=None):
        super().__init__(parent)
        self.sec = sec  # 默认1000秒

    def run(self):
        for i in range(self.sec):
            # time.sleep(1)
            self.sec_changed_signal.emit(i)  # 发射信号
            time.sleep(60 * 60) #

class ReferenceDataDlg(QDialog):

    def __init__(self, parent=None):
        super(ReferenceDataDlg, self).__init__(parent)

        self.model = QSqlTableModel(self)
        self.model.setTable("reference")
        self.model.setSort(ID, Qt.AscendingOrder)
        self.model.setHeaderData(ID, Qt.Horizontal, "编号")
        self.model.setHeaderData(CATEGORY, Qt.Horizontal,"提醒时间")
        self.model.setHeaderData(SHORTDESC, Qt.Horizontal,"提醒内容")
        self.model.setHeaderData(LONGDESC, Qt.Horizontal,"是否需要激活码")
        self.model.setHeaderData(FONTSIZE, Qt.Horizontal,"提醒字号")
        self.model.select()

        self.view = QTableView()
        self.view.setModel(self.model)
        self.view.setSelectionMode(QTableView.SingleSelection)
        self.view.setSelectionBehavior(QTableView.SelectRows)
        self.view.setColumnHidden(ID, True)
        self.view.setColumnWidth(1,1)
        self.view.resizeColumnsToContents()

        self.setWindowIcon(QIcon("ico.ico"))

        buttonBox = QDialogButtonBox()
        showButton = buttonBox.addButton("预览",
                QDialogButtonBox.ActionRole)
        addButton = buttonBox.addButton("增加",
                QDialogButtonBox.ActionRole)
        deleteButton = buttonBox.addButton("删除",
                QDialogButtonBox.ActionRole)
        sortButton = buttonBox.addButton("排序",
                QDialogButtonBox.ActionRole)
        studyButton = buttonBox.addButton("说明",
                QDialogButtonBox.ActionRole)
        if not MAC:
            showButton.setFocusPolicy(Qt.NoFocus)
            addButton.setFocusPolicy(Qt.NoFocus)
            deleteButton.setFocusPolicy(Qt.NoFocus)
            sortButton.setFocusPolicy(Qt.NoFocus)
            studyButton.setFocusPolicy(Qt.NoFocus)

        menu = QMenu(self)
        sortByCategoryAction = menu.addAction("按 提醒时间 排序")
        sortByDescriptionAction = menu.addAction("按 提醒内容 排序")
        sortByIDAction = menu.addAction("按 编号 排序")
        sortButton.setMenu(menu)
        closeButton = buttonBox.addButton(QDialogButtonBox.Close)

        layout = QVBoxLayout()
        layout.addWidget(self.view)
        layout.addWidget(buttonBox)
        self.setLayout(layout)

        showButton.clicked.connect(self.showWarn1)
        addButton.clicked.connect(self.addRecord)
        deleteButton.clicked.connect(self.deleteRecord)
        studyButton.clicked.connect(self.showstudy)
        sortByCategoryAction.triggered.connect(lambda:self.sort(CATEGORY))
        sortByDescriptionAction.triggered.connect(lambda:self.sort(SHORTDESC))
        sortByIDAction.triggered.connect(lambda:self.sort(ID))
        closeButton.clicked.connect(self.accept)
        self.setWindowTitle("WDMSET")
        self.setWindowFlags(Qt.WindowMaximizeButtonHint|Qt.WindowMinimizeButtonHint)
        self.myquery = QSqlQuery()
        self.vQMessageBox = QMessageBox()
        #self.process()
        # self.timer = QTimer()
        # self.timer.setInterval(10000)
        # self.timer.start()
        # self.timer.timeout.connect(self.process)




    def addRecord(self):
        row = self.model.rowCount()
        self.model.insertRow(row)
        index = self.model.index(row, CATEGORY)
        self.view.setCurrentIndex(index)
        self.view.edit(index)


    def deleteRecord(self):
        index = self.view.currentIndex()
        if not index.isValid():
            return
        record = self.model.record(index.row())
        category = record.value(CATEGORY)
        desc = record.value(SHORTDESC)
        box = QMessageBox.question(self, "提醒",
                             ("确定删除 {0} 提醒日期为 {1} 的记录么?"
                              .format(desc, category)),
                             QMessageBox.Yes | QMessageBox.No)
        if ( box ==
                QMessageBox.No):
            return
        self.model.removeRow(index.row())
        self.model.submitAll()
        self.model.select()

    def showstudy(self):
        print(1212)
        QMessageBox.about(self,'操作提醒',"提醒时间 格式样例为 2018-01-01 <br>"
                                      "提醒内容 变量设置：<br>"
                                      "<li>当前日期:{now}</li>"
                                      "<li>剩余天数:{left}</li>")

    def showWarn1(self):
        index = self.view.currentIndex()
        if not index.isValid():
            return
        record = self.model.record(index.row())
        category = record.value(CATEGORY)
        desc = record.value(SHORTDESC)
        warnif = record.value(LONGDESC)
        fontsize = record.value(FONTSIZE)
        print(category)
        print(warnif)
        print(desc)

        waring_t = time.strptime(category, "%Y-%m-%d")
        print(waring_t)
        waring_time = time.mktime(waring_t)
        print(waring_time)
        now = time.localtime(time.time())
        nowtime = time.time()
        print(now)
        print(nowtime)
        print(fontsize)
        str1 = 'QWidget{font-size:' + str(fontsize) + 'px;}'
        print(str)

        left = math.floor((waring_time - nowtime)/(24*60*60))
        print(left)


        desc = desc.replace('{left}','<span style=color:red; font-size=50px >'+str(left)+'</span>')
        warning = "提醒时间："+category+";提醒内容:"+desc;
        #QMessageBox.about(self, "提醒1",desc)
        if warnif == '是':
            infoBox = QInputDialog()
            str1 = 'QWidget{font-size:' + str(fontsize) + 'px;}'
            infoBox.setStyleSheet(str1)
            value, ok = infoBox.getText(infoBox, "提醒", desc, QLineEdit.Normal, '输入激活码，清除本任务')
            print(value)
            #value, ok = infoBox.exec()
            #value, ok = QInputDialog.getText(self, "提醒", desc, QLineEdit.Normal, "输入激活码，清除本任务")
        else:
            infoBox = QMessageBox()
            infoBox.setWindowTitle('提醒')
            infoBox.setText(desc)

            infoBox.setStyleSheet(str1)
            infoBox.exec()


    def showWarn(self,vtime,vdesc):
        category = vtime
        print(category)
        waring_t = time.strptime(category, "%Y-%m-%d")
        print(waring_t)
        waring_time = time.mktime(waring_t)
        print(waring_time)
        now = time.localtime(time.time())
        nowtime = time.time()
        print(now)
        print(nowtime)

        left = math.floor((waring_time - nowtime)/(24*60*60))
        print(left)

        desc = vdesc

        desc = desc.replace('{left}','<span style=color:red; size=50px >'+str(left)+'</span>')
        warning = "提醒时间："+category+";提醒内容:"+desc;
        QMessageBox.about(self, "提醒",desc)
        # QMessageBox.about(self,'提醒',"提醒时间 格式样例为 2018-01-01 <br>"
        #                               "提醒内容 变量设置：<br>"
        #                               "<li>当前日期:{now}</li>"
        #                               "<li>剩余天数:{left}</li>")


    def sort(self, column):
        self.model.setSort(column, Qt.AscendingOrder)
        self.model.select()





    def threadRun(self):
        while True:
            time.sleep(3)
            print('afei')#self.myquery
            select_date = self.myquery.exec('select * from reference')
            print(select_date)
            while self.myquery.next():
                print(str(self.myquery.value(0)) + self.myquery.value(1) + self.myquery.value(2))
                try:
                    self.showWarn(self.myquery.value(1), self.myquery.value(2))
                except ZeroDivisionError as err:  # as 加原因参数名称
                    print('Exception: ', err)


    def war(self):
        self.vQMessageBox.about(self, "提醒", "测试")



#!/usr/bin/python3

import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, delay,myquery,form):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = 1
        self.delay = delay
        self.myquery = myquery
        self.form = form
    def run(self):
        print ("开始线程：" + self.name)
        self.print_time(self.name, self.delay, self.counter)
        print ("退出线程：" + self.name)

    def print_time(self,threadName, delay, counter):
        while True:
            select_date = self.myquery.exec('select * from reference')
            print(select_date)
            while self.myquery.next():
                print(str(self.myquery.value(0)) + self.myquery.value(1) + self.myquery.value(2))
                try:
                    self.showWarn(self.myquery.value(1),self.myquery.value(2))
                except ZeroDivisionError as err:  # as 加原因参数名称
                    print('Exception: ', err)

            print ("%d次执行 %s: %s" % (counter,threadName, time.ctime(time.time())))
            counter += 1
            time.sleep(delay)

    def showWarn(self,vtime,vdesc):
        category = vtime
        print(category)
        waring_t = time.strptime(category, "%Y-%m-%d")
        print(waring_t)
        waring_time = time.mktime(waring_t)
        print(waring_time)
        now = time.localtime(time.time())
        nowtime = time.time()
        print(now)
        print(nowtime)

        left = math.floor((waring_time - nowtime) / (24 * 60 * 60))
        print(left)

        desc = vdesc

        desc = desc.replace('{left}', '<span style=color:red; size=50px >' + str(left) + '</span>')
        warning = "提醒时间：" + category + ";提醒内容:" + desc;
        thread2 = myWaringThread(desc, self.form)
        thread2.start()
        # QMessageBox.about(self,'提醒',"提醒时间 格式样例为 2018-01-01 <br>"
        #                               "提醒内容 变量设置：<br>"
        #                               "<li>当前日期:{now}</li>"
        #                               "<li>剩余天数:{left}</li>")


class myWaringThread (threading.Thread):
    def __init__(self, myquery,form):
        threading.Thread.__init__(self)
        self.myquery = myquery
        self.form = form
    def run(self):
        print ("开始线程：" + self.myquery)
        QMessageBox.about(self.form, "提醒", self.myquery)
        print ("退出线程：" + self.myquery)


# # 创建新线程
# thread1 = myThread(1, "Thread-1", 60)
# #thread2 = myThread(2, "Thread-2", 2)
#
# # 开启新线程
# thread1.start()
# #thread2.start()
# thread1.join()
# #thread2.join()
# print ("退出主线程")

mac = get_mac_address()
def regised():
    is_registered = False
    if os.path.exists('register'):
        print('文件存在')
        try:
            f = open('./register', 'r')
            if f:
                key = f.read()
                if key:
                    encode_str = encode(mac)
                    if encode_str != key:
                        print('注册码不正确,未注册')
                    else:
                        print('已注册')
                        is_registered = True
        except IOError:
            print(IOError)
    else:
        print('文件不存在')

    return is_registered


def main():
    global RUN,mainfram
    app = QApplication(sys.argv)
    filename = os.path.join(os.path.dirname(__file__), "reference.db")
    create = not QFile.exists(filename)

    db = QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName(filename)
    if not db.open():
        QMessageBox.warning(None, "Reference Data",
            "Database Error: {0}".format(db.lastError().text()))
        sys.exit(1)



    if create:
        query = QSqlQuery()
        query.exec_("""CREATE TABLE reference (
                id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
                category VARCHAR(30) NOT NULL,
                shortdesc VARCHAR(200) NOT NULL,
                longdesc VARCHAR(80),
                fontsize number(8))""")

        query.exec_("""CREATE TABLE sjm (
                id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
                sjmm VARCHAR(30) NOT NULL)""")

    main_frame = ReferenceDataDlg()
    ex = FirstWindow()
    ex.pbLogin.clicked.connect(lambda: ex.login(main_frame))
    # ex.pbLogin.clicked.connect(ex.hide)
    ex.close_signal.connect(ex.close)
    # ex.show()
    # myquery = QSqlQuery()

    # thread1 = myThread(1, "Thread-1", 60, myquery,form)
    # thread1.start()

    sys.exit(app.exec_())

main()